package com.example.compose

import android.content.ClipData
import android.content.ClipDescription
import androidx.annotation.DrawableRes
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.draganddrop.dragAndDropSource
import androidx.compose.foundation.draganddrop.dragAndDropTarget
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draganddrop.DragAndDropEvent
import androidx.compose.ui.draganddrop.DragAndDropTarget
import androidx.compose.ui.draganddrop.DragAndDropTransferData
import androidx.compose.ui.draganddrop.mimeTypes
import androidx.compose.ui.draganddrop.toAndroidDragEvent
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview


@OptIn(ExperimentalFoundationApi::class)
@Composable
fun DragImage(@DrawableRes imageId: Int) {
    Image(
        painter = painterResource(id = imageId),
        contentDescription = "",
        modifier = Modifier.dragAndDropSource {
            detectTapGestures(
                onLongPress = {
                    startTransfer(
                        DragAndDropTransferData(
                            clipData = ClipData.newPlainText(
                                "Image url",
                                imageId.toString()
                            )
                        )
                    )
                }
            )
        }
    )
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun DragTargetImage(@DrawableRes imageId: Int) {
    var urlState by remember {
        mutableStateOf(imageId.toString())
    }
    var tintColor by remember {
        mutableStateOf(Color(0xFFe5e4e2))
    }
    val dndTarget = remember {
        object : DragAndDropTarget {
            override fun onDrop(event: DragAndDropEvent): Boolean {
                val draggedData = event.toAndroidDragEvent()
                    .clipData.getItemAt(0).text
                urlState = draggedData.toString()
                return true
            }

            override fun onEntered(event: DragAndDropEvent) {
                super.onEntered(event)
                tintColor = Color(0xFFAD53E4)
            }

            override fun onEnded(event: DragAndDropEvent) {
                super.onEnded(event)
                tintColor = Color(0xFFe5e4e2)
            }

            override fun onExited(event: DragAndDropEvent) {
                super.onExited(event)
                tintColor = Color(0xFFe5e4e2)
            }
        }
    }
    Image(
        modifier = Modifier.dragAndDropTarget(
            shouldStartDragAndDrop = { event ->
                event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_PLAIN)
            },
            target = dndTarget
        ),
        painter = painterResource(id = urlState.toInt()),
        contentDescription = "",
        colorFilter = ColorFilter.tint(color = tintColor, blendMode = BlendMode.Modulate)
    )
}


@Preview
@Composable
private fun DragImagePreview() {
    val bella by remember {
        mutableIntStateOf(R.drawable.bella)
    }
    val nox by remember {
        mutableIntStateOf(R.drawable.nox)
    }
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.SpaceAround,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        DragImage(imageId = bella)
        DragTargetImage(imageId = nox)
    }

}